package com.jian.mygame;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;

import android.util.Log;
import android.view.MotionEvent;

class MultiTouchHandler extends Object {
    //private TestView view;
    //private final int Pitch = 30;
	static public final int NO_EVENT = 0;
	static public final int LEFT_EVENT = 1;
	static public final int RIGHT_EVENT = 2;
	
	public int mSpliterX = 800;
	public boolean mLeftRightLimitEn = false;
	
	class MyTouchEvent {
		public float x;
		public float y;
		public float pressure;
		public int   action;
		//public int id;
		public int left_right = NO_EVENT;
		
		public float getX(){
			return x;
		}
		
		public float getY(){
			return y;
		}
		
		public int getAction(){
			return action;
		}
		
		public float getPressure(){
			return pressure;
		}
		
		//public MotionEvent ev;
    }

    Hashtable<Integer, MyTouchEvent> points;
    
    class MultiTouchEvent {
    	public boolean has_left_ev;
    	public MyTouchEvent left_ev;
    	public boolean has_right_ev;
    	public MyTouchEvent right_ev;
    }
    MultiTouchEvent mMultiTouchEvent;

    
    public MultiTouchHandler(){
    	init();
    }
    
    void init(){
    	points = new Hashtable<Integer, MyTouchEvent>();
    	points.clear();
    	mMultiTouchEvent = new MultiTouchEvent();
    	mMultiTouchEvent.has_left_ev = false;
    	mMultiTouchEvent.has_right_ev = false;
    	
    	mLeftRightLimitEn = false;
    }
    
	void put_points(MotionEvent ev, int pointerID ) {
	    int count = ev.getPointerCount();
	    int currentLeftRight = NO_EVENT;
	    
	    mMultiTouchEvent.has_left_ev = false;
	    mMultiTouchEvent.has_right_ev = false;
	    for (int i=0; i < count; i++) {
			int id = ev.getPointerId(i);
			MyTouchEvent current_mev = new MyTouchEvent();
			MyTouchEvent prev_ev = points.get(id);

			current_mev.x = ev.getX(i);
			current_mev.y = ev.getY(i);
			current_mev.pressure = ev.getPressure(i);
			current_mev.action = ev.getAction();
			
			//Replace Action
			switch (ev.getAction() & MotionEvent.ACTION_MASK) { 
			case MotionEvent.ACTION_POINTER_DOWN :
				current_mev.action = MotionEvent.ACTION_DOWN;
				break;
			case MotionEvent.ACTION_POINTER_UP:
				if( pointerID == id ) {
					current_mev.action = MotionEvent.ACTION_UP;
				} else {
					//For other pointer keep previous action
					current_mev.action = points.get(id).getAction();
				}
				break;
			default:
				break;
			}
			
			
			if( prev_ev == null ) {
				if( current_mev.x < mSpliterX ) {
					currentLeftRight = LEFT_EVENT;
				} else {
					currentLeftRight = RIGHT_EVENT;
				}
				
				current_mev.left_right = currentLeftRight;
				points.put(id, current_mev);
			} else {
				if( prev_ev.left_right == LEFT_EVENT ){
					current_mev.left_right = LEFT_EVENT;
					
					if( mLeftRightLimitEn ){
						if( current_mev.x < mSpliterX ) {
						} else {
							current_mev.x = mSpliterX-1;
							current_mev.y = prev_ev.getY();
						}
					}

					points.put(id, current_mev);
				} else if ( prev_ev.left_right == RIGHT_EVENT ){
					current_mev.left_right = RIGHT_EVENT;
					
					if( mLeftRightLimitEn ){
						if( current_mev.x >= mSpliterX ) {
						} else {
							current_mev.x = mSpliterX;
							current_mev.y = prev_ev.getY();
						}
					}
					
					points.put(id, current_mev);
				} else {
					
				}
			}
			
			if( current_mev.left_right == LEFT_EVENT ) {
				mMultiTouchEvent.has_left_ev = true;
				mMultiTouchEvent.left_ev = current_mev;
			} else if( current_mev.left_right == RIGHT_EVENT  ) {
				mMultiTouchEvent.has_right_ev = true;
				mMultiTouchEvent.right_ev = current_mev;
			}
	    }
	 
		if( mMultiTouchEvent.has_left_ev ) {
			printDebugLog( mMultiTouchEvent.left_ev.action, "LEFT_EV" + 
												" X: " + mMultiTouchEvent.left_ev.getX() + 
												" Y: " + mMultiTouchEvent.left_ev.getY() + 
	  			                                " Cnt:" + count );
		} 
		
		if( mMultiTouchEvent.has_right_ev ) {
			printDebugLog( mMultiTouchEvent.right_ev.action, "RIGHT_EV" +
												" X: " + mMultiTouchEvent.right_ev.getX() + 
												" Y: " + mMultiTouchEvent.right_ev.getY() + 
				                                " Cnt:" + count );
		}    
	    //return currentLeftRight;
	}

	public MultiTouchEvent onTouchEvent(MotionEvent ev) {
	    int action = ev.getAction();
	    
	    printSamples( ev );
	    
	    switch (action & MotionEvent.ACTION_MASK) {
		    case MotionEvent.ACTION_DOWN:
		    	put_points(ev, 0);
				break;
		    case MotionEvent.ACTION_POINTER_DOWN:
		    	put_points(ev, 0);
				break;
		    case MotionEvent.ACTION_MOVE:
		    	put_points(ev, 0);
				break;
		    case MotionEvent.ACTION_UP:
		    	put_points(ev, 0);
				points.remove(ev.getPointerId(0));
				break;
		    case MotionEvent.ACTION_POINTER_UP:
				int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
				    >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
	    		put_points(ev, ev.getPointerId(index));
	    		points.remove(ev.getPointerId(index));
				break;
			default:
				break;
	    }
	    
	    printDebugLog( action, "");
	    
	    return mMultiTouchEvent;
	}
	
	void printSamples(MotionEvent ev) {
		final int historySize = ev.getHistorySize();
		final int pointerCount = ev.getPointerCount();
		
		
		for (int h = 0; h < historySize; h++) {         
			Log.d("RawEV", " [Hist] At time: " + ev.getHistoricalEventTime(h));         
			
			for (int p = 0; p < pointerCount; p++) {             
				Log.d("RawEV", " [Hist] pointer " +                 
								  ev.getPointerId(p) + " ( " + 
								  ev.getHistoricalX(p, h) + " , " +
								  ev.getHistoricalY(p, h) );
			}     
		}     
		
		Log.d("RawEV", " [New ] At time: " + ev.getEventTime());  
		for (int p = 0; p < pointerCount; p++) {
			Log.d("RawEV", " [New ] pointer " +                 
							  ev.getPointerId(p) + " ( " + 
							  ev.getX(p) + " , " +
							  ev.getY(p) + 
							  translateActionName(ev.getAction()) + " )");

		} 
		
		//Log.d("RawEV", ev.toString());  
		
	}
	
	static public String translateActionName( int action ) {
		String strActionName = "UNKNOWN";
		
	    switch (action & MotionEvent.ACTION_MASK) {
	    case MotionEvent.ACTION_DOWN:
	    	strActionName = "ACTION_DOWN";
			break;
	    case MotionEvent.ACTION_POINTER_DOWN:
	    	strActionName = "ACTION_POINTER_DOWN";
			break;
	    case MotionEvent.ACTION_MOVE:
	    	strActionName =  "ACTION_MOVE";
			break;
	    case MotionEvent.ACTION_UP:
	    	strActionName = "ACTION_UP";
			break;
	    case MotionEvent.ACTION_POINTER_UP:
	    	strActionName =  "ACTION_POINTER_UP";
			break;
		default:
			strActionName = "Other Action ID:" + String.valueOf(action);
			break;
	    }
	    
	    return strActionName;
	}
	
	static private void printDebugLog( int action, String strPrefix ) {
		//int action = ev.getAction();
		
	    switch (action & MotionEvent.ACTION_MASK) {
	    case MotionEvent.ACTION_DOWN:
	    	Log.d("MultiTouchEvent", strPrefix + "ACTION_DOWN");
			break;
	    case MotionEvent.ACTION_POINTER_DOWN:
	    	Log.d("MultiTouchEvent", strPrefix + "ACTION_POINTER_DOWN");
			break;
	    case MotionEvent.ACTION_MOVE:
	    	Log.d("MultiTouchEvent", strPrefix + "ACTION_MOVE");
			break;
	    case MotionEvent.ACTION_UP:
	    	Log.d("MultiTouchEvent", strPrefix + "ACTION_UP");
			break;
	    case MotionEvent.ACTION_POINTER_UP:
	    	Log.d("MultiTouchEvent", strPrefix + "ACTION_POINTER_UP");
			break;
		default:
			Log.d("MultiTouchEvent", strPrefix + "Other Action ID:" + String.valueOf(action));
			break;
	    }
	}
	
	/*
	static public MotionEvent getMotionEvent( int left_right ) {
		MotionEvent ev = null;
		
	    Set keys = points.keySet();
	    for (Iterator i = keys.iterator(); i.hasNext();) {
			Integer id = (Integer)i.next();
			MyTouchEvent p = points.get(id);
			
			if( p.left_right == left_right ) {
				ev = p.ev;
				break;
			}
	    }
	    
		return ev;
	}
	*/
	/*
	@Override
	public void onDraw(Canvas canvas) {
	    canvas.drawColor(Color.WHITE);
	    Paint paint = new Paint();
	    Set keys = points.keySet();
	    for (Iterator i = keys.iterator(); i.hasNext();) {
			Integer id = (Integer)i.next();

			switch (id) {
				case 0:  paint.setColor(Color.RED);   break;
				case 1:  paint.setColor(Color.GREEN); break;
				case 2:  paint.setColor(Color.BLUE);  break;
				default: paint.setColor(Color.BLACK); break;
			}

			paint.setAlpha(128);
			TouchPoint p = points.get(id);
			canvas.drawCircle(p.x, p.y, 10+p.p*200, paint);
	    }
	}
	 */

    /** Called when the activity is first created. */
    /*
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
		view = new TestView(this);
		points = new Hashtable<Integer, TouchPoint>();
	setContentView(view);
    }
    */
}
